// tokens.rs
use std::fmt;

#[derive(Debug, Clone, PartialEq)]
pub struct Token {
    pub token_type: TokenType,
    pub lexeme: String,
    pub line: usize,
}

// impl<'a> Token<'a> {
//     pub fn line(&self) -> usize {
//         // 计算 token 所在行号（从1开始）
//         self.line.start_pos().line_col().0
//     }
// }

impl fmt::Display for Token {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self.token_type == TokenType::ErrorToken {
            true => write!(
                f,
                "{} type A at Line {}: Mysterious character `{}`.",
                self.token_type, self.line, self.lexeme
            ),
            false => write!(
                f,
                "{} {} at Line {}.",
                self.token_type, self.lexeme, self.line
            ),
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum TokenType {
    // 关键字
    Const,
    Int,
    Void,
    If,
    Else,
    While,
    Break,
    Continue,
    Return,
    For,

    // 运算符
    Plus,
    Minus,
    Mul,
    Div,
    Mod,
    Assign,
    Eq,
    Neq,
    Lt,
    Gt,
    Le,
    Ge,
    Not,
    And,
    Or,

    // 标点符号
    LParen,
    RParen,
    LBrace,
    RBrace,
    LBrackt,
    RBrackt,
    Comma,
    Semicolon,

    // 标识符和常量
    Identifier,
    IntegerConstant,

    // 错误标记
    ErrorToken,
}

// 实现 Display 以便输出
impl fmt::Display for TokenType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            TokenType::Const => write!(f, "CONST"),
            TokenType::Int => write!(f, "INT"),
            TokenType::Void => write!(f, "VOID"),
            TokenType::If => write!(f, "IF"),
            TokenType::Else => write!(f, "ELSE"),
            TokenType::While => write!(f, "WHILE"),
            TokenType::Break => write!(f, "BREAK"),
            TokenType::Continue => write!(f, "CONTINUE"),
            TokenType::Return => write!(f, "RETURN"),
            TokenType::For => write!(f, "FOR"),
            TokenType::Plus => write!(f, "PLUS"),
            TokenType::Minus => write!(f, "MINUS"),
            TokenType::Mul => write!(f, "MUL"),
            TokenType::Div => write!(f, "DIV"),
            TokenType::Mod => write!(f, "MOD"),
            TokenType::Assign => write!(f, "ASSIGN"),
            TokenType::Eq => write!(f, "EQ"),
            TokenType::Neq => write!(f, "NEQ"),
            TokenType::Lt => write!(f, "LT"),
            TokenType::Gt => write!(f, "GT"),
            TokenType::Le => write!(f, "LE"),
            TokenType::Ge => write!(f, "GE"),
            TokenType::Not => write!(f, "NOT"),
            TokenType::And => write!(f, "AND"),
            TokenType::Or => write!(f, "OR"),
            TokenType::LParen => write!(f, "L_PAREN"),
            TokenType::RParen => write!(f, "R_PAREN"),
            TokenType::LBrace => write!(f, "L_BRACE"),
            TokenType::RBrace => write!(f, "R_BRACE"),
            TokenType::LBrackt => write!(f, "L_BRACKT"),
            TokenType::RBrackt => write!(f, "R_BRACKT"),
            TokenType::Comma => write!(f, "COMMA"),
            TokenType::Semicolon => write!(f, "SEMICOLON"),
            TokenType::Identifier => write!(f, "IDENT"),
            TokenType::IntegerConstant => write!(f, "INTEGER_CONST"),
            TokenType::ErrorToken => write!(f, "Error"),
        }
    }
}
